package com.wiseman.writing;

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Random;
import java.util.TreeSet;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.res.AssetFileDescriptor;
import android.content.res.AssetManager;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import cn.domob.android.ads.DomobInterstitialAd;

import com.wiseman.writing.utility.PinyinUtil;
import com.wiseman.writing.utility.StrokeView;
import com.wiseman.writing.utility.StrokeView.Listener;
import com.wiseman.writing.utility.database.WDatabase;
import com.wiseman.writing.utility.parsedata.TxtIndexer;

public class StrokeActivity extends Activity implements OnClickListener, Listener, ConstValue {

	private StrokeView mStrokeView;
	private AlertDialog mDialog;
	int mFontSize = 300;

	private TextView mTVCharName;
	private TextView mTVStrokeNum;

	GridView mGridView;
	StrokeSeqAdapter mAdapter = null;

	Dialog mSettingDialog = null;
	private String mStrChars;
	private int mCharIndex;

	private WDatabase mDatabase;

	private LinearLayout mPinyinPanel;
	private DomobInterstitialAd mInterstitialAd;
	private Random mRandom;
	StringBuffer mFavorContent = null;
	private ImageButton mFavorButton;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main_activity);

		createDialog();

		mStrokeView = (StrokeView) findViewById(R.id.viewStroke);

		Log.i("version", android.os.Build.VERSION.SDK_INT + " ");

		final char c = getIntent().getCharExtra(INTENTNAME_CHARCODE, '永');
		mStrChars = getIntent().getStringExtra(INTENTNAME_CHARLIST);

		if (mStrChars != null) {
			mCharIndex = getIntent().getIntExtra(INTENTNAME_CHARINDEX, 0);
			checkNavStates();
		} else {
			mStrChars = Character.toString(c);
			mCharIndex = 0;
		}

		// get view width & height before it display.
		ViewTreeObserver vto = mStrokeView.getViewTreeObserver();
		vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
			@SuppressWarnings("deprecation")
			@Override
			public void onGlobalLayout() {

				mStrokeView.getViewTreeObserver().removeGlobalOnLayoutListener(this);

				mFontSize = mStrokeView.getHeight() - 20;
				if (mStrokeView.setChar(c, mFontSize) == false) {
					mDialog.show();
				} else {

					mStrokeView.showChar(null, c, mFontSize);
					String strItem = getResources().getString(R.string.strokeNumItem);
					String strokeNum = String.format(strItem, mStrokeView.getStrokeNum());
					mTVStrokeNum.setText(strokeNum);
				}
			}
		});

		mTVCharName = (TextView) findViewById(R.id.tvCharName);

		mTVStrokeNum = (TextView) findViewById(R.id.tvStrokeNum);
		mGridView = (GridView) findViewById(R.id.gvStroke);

		mPinyinPanel = (LinearLayout) findViewById(R.id.pinyinPanel);

		String strItem = getResources().getString(R.string.chineseItem);
		String charName = String.format(strItem, c);
		mTVCharName.setText(charName);

		setPinyinPanel(c);

		mAdapter = new StrokeSeqAdapter(this, c);
		mGridView.setAdapter(mAdapter);

		mStrokeView.setListener(this);

		createSettingDialog();

		mDatabase = new WDatabase(this, TABLE_NAME) {
			@Override
			public void fillKeys() {
				mKeyMap.put(KEY_CHARS, "TEXT");
			}
		};

		mDatabase.open();

		mInterstitialAd = DomoAd.createInterstitialAd(this);

		mRandom = new Random();

		// ImageButton
		ImageButton ib = (ImageButton) findViewById(R.id.btDetailInfo);
		ib.setOnClickListener(this);

		mFavorButton = (ImageButton) findViewById(R.id.btFavor);
		mFavorButton.setOnClickListener(this);

		// favor;
		mFavorContent = new StringBuffer(AppUtil.getFavorData(this));
		checkFavorStates();
	}

	void setPinyinPanel(char c) {
		mPinyinPanel.removeAllViews();
		OnClickListener ls = new OnClickListener() {

			@Override
			public void onClick(View v) {
				String pinyin = (String) v.getTag();
				playPinYinVoice(pinyin);
			}
		};

		String[] pyArray = getPinYin(c);

		if (pyArray != null && pyArray.length > 0) {

			LinearLayout layout = null;

			LinearLayout.LayoutParams p = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
					LayoutParams.WRAP_CONTENT);

			p.gravity = Gravity.CENTER_VERTICAL;

			LinearLayout.LayoutParams p1 = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
					LayoutParams.WRAP_CONTENT);
			p1.gravity = Gravity.CENTER_VERTICAL;
			p1.rightMargin = 10;

			for (int i = 0; i < pyArray.length; i++) {
				if (i % 2 == 0) {
					if (layout != null) {
						mPinyinPanel.addView(layout);
					}
					layout = new LinearLayout(this);
				}

				String py = pyArray[i];

				TextView tv = new TextView(StrokeActivity.this);
				tv.setText(py);
				tv.setTextSize(24);

				layout.addView(tv, p);

				String pyHasTone = PinyinUtil.toPinYinHasTone(py);
				if (isHasVoice(pyHasTone)) {
					ImageButton ibt = new ImageButton(StrokeActivity.this);
					ibt.setBackgroundResource(R.drawable.btn_speaker_bg);
					ibt.setTag(pyHasTone);
					ibt.setOnClickListener(ls);
					layout.addView(ibt, p1);
				}

			}

			mPinyinPanel.addView(layout);
		}

	}

	private String[] getPinYin(char c) {

		String py2312 = "pinyin2312";
		String py2312idx = "pinyin2312.idx";
		String pyinfo[] = null;

		try {
			InputStream inSrc = getAssets().open(py2312, AssetManager.ACCESS_RANDOM);
			InputStream inIdx = getAssets().open(py2312idx, AssetManager.ACCESS_RANDOM);
			// inSrc.mark(-1);
			// inIdx.mark(-1);

			String item = TxtIndexer.getPinyinFromAssert(inSrc, inIdx, c);
			// Log.i("My Android", pinyin);
			// inSrc.reset();
			// inIdx.reset();
			if (item != null && item.contains(":")) {

				String info[] = item.split(":");

				if (info.length == 2) {
					if (info[1].contains(",")) {
						pyinfo = info[1].split(",");
					} else {
						pyinfo = new String[1];
						pyinfo[0] = info[1];
					}
				}
			}

			inSrc.close();
			inIdx.close();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return pyinfo;
	}

	@Override
	protected void onPause() {
		if (mSaveCharSet.size() > 0) {
			saveToDatabase();
		}

		AppUtil.commitFavorData(this, mFavorContent.toString());

		super.onPause();
	}

	@Override
	protected void onDestroy() {

		mDatabase.close();
		super.onDestroy();
	}

	private void createSettingDialog() {
		mSettingDialog = new Dialog(this, 0);
		mSettingDialog.setContentView(R.layout.setting);
		mSettingDialog.setTitle(R.string.Setting);

		final String pref_demospeed = "preference demo speed";
		final String pref_writingSensivity = "preference writing sensivity";

		final SharedPreferences preference = getPreferences(MODE_PRIVATE);

		int demospeed = preference.getInt(pref_demospeed, 3);
		int writingSensivity = preference.getInt(pref_writingSensivity, 3);

		// init speed.
		mStrokeView.setDemoSpeed(demospeed);
		mStrokeView.setWrtingSensivity(writingSensivity);
		// end.

		final SeekBar sbDemo = (SeekBar) mSettingDialog.findViewById(R.id.seekbar_Demo);
		sbDemo.setMax(5);
		sbDemo.setProgress(demospeed);

		final SeekBar sbWriting = (SeekBar) mSettingDialog.findViewById(R.id.seekbar_writing);
		sbWriting.setMax(5);
		sbWriting.setProgress(writingSensivity);

		View bt = mSettingDialog.findViewById(R.id.btSure);
		bt.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				int v1 = sbDemo.getProgress();
				Editor editor = preference.edit();
				editor.putInt(pref_demospeed, v1);

				int v2 = sbWriting.getProgress();
				editor.putInt(pref_writingSensivity, v2);

				editor.commit();

				mStrokeView.setDemoSpeed(v1);
				mStrokeView.setWrtingSensivity(v2);

				mSettingDialog.dismiss();
			}
		});

		bt = mSettingDialog.findViewById(R.id.btCancel);
		bt.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				mSettingDialog.dismiss();
			}
		});

	}

	Menu mMainMenu = null;

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
		checkNavStates();
		return super.onPrepareOptionsMenu(menu);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// <item
		// android:id="@+id/btPrevChar"
		// android:showAsAction="ifRoom"
		// android:title="@string/prevChar"/>
		// <item
		// android:id="@+id/btNextChar"
		// android:showAsAction="ifRoom"
		// android:title="@string/nextChar"/>
		// <item
		// android:id="@+id/btSetting"
		// android:orderInCategory="100"
		// android:showAsAction="never"
		// android:title="@string/Setting"/>

		getMenuInflater().inflate(R.menu.activity_main, menu);

		mMainMenu = menu;

		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {

		switch (item.getItemId()) {
		// case R.id.btDemo:
		// mStrokeView.demoChar();
		// break;
		// case R.id.btWrite:
		// mStrokeView.writeChar();
		// break;
		case R.id.btSetting:
			mSettingDialog.show();
			break;
		case R.id.btPrevChar:
			prevChar();
			break;
		case R.id.btNextChar:
			nextChar();
			break;
		case R.id.btDetailInfo:
			detailInfo();
			break;
		case R.id.btShare:
			AppUtil.share(this);
			break;
		case R.id.btCommit_Score:
			AppUtil.commitScore(this);
			break;
		case R.id.btHelp:
			SplashActivity.showIntro(this, false);
			break;
		case R.id.btAbout:
			startActivity(new Intent().setClass(this, About.class));
			break;
		default:
			break;
		}

		return super.onOptionsItemSelected(item);
	}

	void createDialog() {
		if (mDialog == null) {
			Builder b = new AlertDialog.Builder(this);
			b.setMessage(getString(R.string.msgNotStroke));
			b.setPositiveButton(getString(R.string.btSure), new DialogInterface.OnClickListener() {
				@Override
				public void onClick(DialogInterface dialog, int which) {
					mDialog.dismiss();
					finish();
				}
			});
			b.setOnCancelListener(new DialogInterface.OnCancelListener() {
				@Override
				public void onCancel(DialogInterface dialog) {
					finish();
				}
			});

			mDialog = b.create();
		}
	}

	@Override
	public void onClick(View v) {
		int id = v.getId();

		switch (id) {
		// case R.id.btDemo:
		// mStrokeView.demoChar();
		// break;
		// case R.id.btWrite:
		// mStrokeView.writeChar();
		// break;
		case R.id.btSetting:
			mSettingDialog.show();
			break;
		case R.id.btPrevChar:
			prevChar();
			break;
		case R.id.btNextChar:
			nextChar();
			break;
		case R.id.btDetailInfo:
			detailInfo();
			break;
		case R.id.btFavor:
			swichFavor(v);
			break;
		default:
			break;
		}

	}

	void setFavorButtonStates(View v, boolean bFavor) {
		v.setBackgroundResource(bFavor ? R.drawable.favor_enable : R.drawable.favor_disable);
	}

	private void detailInfo() {
		final String requestUri = "http://dict.baidu.com/s?wd=";
		char c = mStrChars.charAt(mCharIndex);
		Intent intent = new Intent();
		intent.setAction(Intent.ACTION_VIEW);
		intent.setData(Uri.parse(requestUri + c));

		try {
			startActivity(intent);
		} catch (Exception e) {
			// TODO: handle exception
		}
	}

	private void setChar(char c) {

		if (mStrokeView.setChar(c, mFontSize) == false) {
			mDialog.show();
		} else {
			mStrokeView.showChar(null, c, mFontSize);
			mStrokeView.invalidate();
		}

		String strItem = getResources().getString(R.string.chineseItem);
		String charName = String.format(strItem, c);
		mTVCharName.setText(charName);

		strItem = getResources().getString(R.string.strokeNumItem);
		String strokeNum = String.format(strItem, mStrokeView.getStrokeNum());
		mTVStrokeNum.setText(strokeNum);

		setPinyinPanel(c);

		mAdapter = new StrokeSeqAdapter(this, c);
		mGridView.setAdapter(mAdapter);
	}

	void checkFavorStates() {
		setFavorButtonStates(mFavorButton, mFavorContent.indexOf(mStrChars.substring(mCharIndex, mCharIndex + 1)) != -1);
	}

	void checkNavStates() {

		// if (android.os.Build.VERSION.SDK_INT > 10) {
		//
		// // ActionBar bar = getActionBar();
		// // bar.getTabAt(index);
		// }
		//

		if (mMainMenu != null) {
			mMainMenu.getItem(0).setEnabled(mCharIndex != 0);
			mMainMenu.getItem(1).setEnabled(mCharIndex != mStrChars.length() - 1);
		}

	}

	int mCountNextChar = 0;
	int mCountPrevChar = 0;

	private void nextChar() {

		if (mStrChars != null && mCharIndex != mStrChars.length() - 1) {
			mCharIndex++;
			setChar(mStrChars.charAt(mCharIndex));
			mCountNextChar++;
			checkNavStates();
			checkFavorStates();

			if (mCountNextChar % 5 == 0) {
				DomoAd.showInterstitialAd(this, mInterstitialAd);
			}

		}
	}

	private void prevChar() {
		if (mStrChars != null && mCharIndex != 0) {
			mCharIndex--;
			setChar(mStrChars.charAt(mCharIndex));
			mCountPrevChar++;
			checkNavStates();
			checkFavorStates();

			if (mCountPrevChar % 5 == 0) {
				DomoAd.showInterstitialAd(this, mInterstitialAd);
			}

		}
	}

	TreeSet<Character> mSaveCharSet = new TreeSet<Character>();

	@Override
	public void finishedWriting() {
		// record.
		// play sound.

		try {
			playVoice(getAssets().openFd("cheer" + mRandom.nextInt(4) + ".mp3"));
		} catch (Exception e) {
			// TODO: handle exception
		}
		//

		mSaveCharSet.add(mStrChars.charAt(mCharIndex));

		if (mStrChars == null || mCharIndex == mStrChars.length() - 1)
			return;

		nextChar();
	}

	void saveToDatabase() {

		boolean isUpdate = false;

		StrokeDBData oldData = new StrokeDBData();

		if (mDatabase.getDataByDate(oldData)) {
			String chars = oldData.mChars;

			for (int i = 0; i < chars.length(); i++) {
				mSaveCharSet.add(chars.charAt(i));
			}

			isUpdate = true;
		}

		String datastr = new String();
		for (char c : mSaveCharSet) {
			datastr += c;
		}

		StrokeDBData newData = new StrokeDBData(datastr);

		if (isUpdate) {
			mDatabase.updateData(newData);
		} else {
			mDatabase.insertData(newData);
		}
	}

	boolean isHasVoice(String pinyin) {
		String url = "http://bs.baidu.com/handian/" + pinyin + ".mp3";

		// return isConnect(url) != null;
		return true;
	}

	void playPinYinVoice(String pinyin) {
		String url = "http://bs.baidu.com/handian/" + pinyin + ".mp3";
		playVoice(url);
	}

	void playVoice(String url) {

		MediaPlayer player = new MediaPlayer();
		try {
			player.setDataSource(url);
			player.prepare();
			player.start();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	void playVoice(AssetFileDescriptor afd) {

		MediaPlayer player = new MediaPlayer();
		try {
			player.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
			player.prepare();
			player.start();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 功能描述 : 检测当前URL是否可连接或是否有效, 最多连接网络 5 次, 如果 5 次都不成功说明该地址不存在或视为无效地址.
	 * 
	 * @param url
	 *            指定URL网络地址
	 * 
	 * @return String
	 */
	private synchronized String isConnect(String url) {
		int counts = 0;
		String succ = null;
		if (url == null || url.length() <= 0) {
			return succ;
		}
		while (counts < 5) {
			try {
				URL urlStr = new URL(url);
				HttpURLConnection connection = (HttpURLConnection) urlStr.openConnection();
				int state = connection.getResponseCode();
				if (state == 200) {
					succ = connection.getURL().toString();
				}
				break;
			} catch (Exception ex) {
				counts++;
				continue;
			}
		}
		return succ;
	}

	void swichFavor(View v) {
		int index = mFavorContent.indexOf(mStrChars.substring(mCharIndex, mCharIndex + 1));

		boolean bFavor = index != -1;
		if (bFavor) {
			mFavorContent.deleteCharAt(index);
		} else {
			mFavorContent.insert(0, mStrChars.charAt(mCharIndex));
		}

		setFavorButtonStates(v, !bFavor);
	};

}
